package com.example.controller;

import com.example.common.RequirePermission;
import com.example.common.Result;
import com.example.common.PageResult;
import com.example.dto.AppointmentDTO;
import com.example.service.AppointmentService;
import com.example.vo.AppointmentVO;
import com.example.vo.StoreManagerScheduleVO;
import com.example.vo.TimeSlotAvailabilityVO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.format.annotation.DateTimeFormat;
import org.springframework.web.bind.annotation.*;

import java.time.LocalDate;
import java.util.List;
import java.util.Map;

/**
 * 预约控制器
 */
@Slf4j
@RestController
@RequestMapping("/api/appointment")
@CrossOrigin
public class AppointmentController {
    
    @Autowired
    private AppointmentService appointmentService;
    
    /**
     * 创建预约
     */
    @PostMapping("/create")
    @RequirePermission("user:appointment:create")
    public Result<Void> createAppointment(@RequestBody AppointmentDTO appointmentDTO) {
        try {
            return appointmentService.createAppointment(appointmentDTO);
        } catch (Exception e) {
            log.error("创建预约失败", e);
            return Result.error("创建预约失败：" + e.getMessage());
        }
    }
    
    /**
     * 取消预约
     */
    @PutMapping("/cancel/{id}")
    @RequirePermission("user:appointment:cancel")
    public Result<Void> cancelAppointment(@PathVariable Long id) {
        try {
            return appointmentService.cancelAppointment(id);
        } catch (Exception e) {
            log.error("取消预约失败", e);
            return Result.error("取消预约失败：" + e.getMessage());
        }
    }
    
    /**
     * 根据ID查询预约详情
     */
    @GetMapping("/{id}")
    @RequirePermission("user:appointment:view")
    public Result<AppointmentVO> getAppointmentById(@PathVariable Long id) {
        try {
            return appointmentService.getAppointmentById(id);
        } catch (Exception e) {
            log.error("查询预约详情失败", e);
            return Result.error("查询预约详情失败：" + e.getMessage());
        }
    }
    
    /**
     * 获取当前用户的预约列表
     */
    @GetMapping("/my")
    @RequirePermission("user:appointment:view")
    public Result<List<AppointmentVO>> getMyAppointments() {
        try {
            return appointmentService.getMyAppointments();
        } catch (Exception e) {
            log.error("查询我的预约列表失败", e);
            return Result.error("查询我的预约列表失败：" + e.getMessage());
        }
    }
    
    /**
     * 获取当前店长的预约列表
     */
    @GetMapping("/store-manager")
    @RequirePermission("store:appointment:view")
    public Result<List<AppointmentVO>> getStoreManagerAppointments(
            @RequestParam(required = false) String startDate,
            @RequestParam(required = false) String endDate,
            @RequestParam(required = false) Integer status,
            @RequestParam(required = false) String serviceType) {
        try {
            // 如果没有任何搜索参数，使用原来的方法
            if (startDate == null && endDate == null && status == null &&
                (serviceType == null || serviceType.trim().isEmpty())) {
                return appointmentService.getStoreManagerAppointments();
            }
            // 有搜索参数时使用新的方法
            return appointmentService.getStoreManagerAppointments(startDate, endDate, status, serviceType);
        } catch (Exception e) {
            log.error("查询店长预约列表失败", e);
            return Result.error("查询店长预约列表失败：" + e.getMessage());
        }
    }
    
    /**
     * 分页查询预约记录
     */
    @GetMapping("/page")
    @RequirePermission("admin:appointment:view")
    public Result<PageResult<AppointmentVO>> getAppointmentPage(
            @RequestParam(defaultValue = "1") int page,
            @RequestParam(defaultValue = "10") int size,
            @RequestParam(required = false) Long userId,
            @RequestParam(required = false) Long storeManagerId,
            @RequestParam(required = false) Integer status) {
        try {
            return appointmentService.getAppointmentPage(page, size, userId, storeManagerId, status);
        } catch (Exception e) {
            log.error("分页查询预约记录失败", e);
            return Result.error("分页查询预约记录失败：" + e.getMessage());
        }
    }

    /**
     * 管理员获取所有用户预约记录（分页）
     */
    @GetMapping("/admin/all")
    @RequirePermission("admin:appointment:list")
    public Result<PageResult<AppointmentVO>> getAdminAppointmentPage(
            @RequestParam(defaultValue = "1") int page,
            @RequestParam(defaultValue = "10") int size,
            @RequestParam(required = false) String username,
            @RequestParam(required = false) String storeManagerName,
            @RequestParam(required = false) Integer status,
            @RequestParam(required = false) String packageName,
            @RequestParam(required = false) String startDate,
            @RequestParam(required = false) String endDate) {
        try {
            return appointmentService.getAdminAppointmentPage(page, size, username, storeManagerName, status, packageName, startDate, endDate);
        } catch (Exception e) {
            log.error("管理员查询预约记录失败", e);
            return Result.error("管理员查询预约记录失败：" + e.getMessage());
        }
    }
    
    /**
     * 获取所有店长的排班时间表
     */
    @GetMapping("/schedules")
    @RequirePermission("user:schedule:view")
    public Result<List<StoreManagerScheduleVO>> getAllStoreManagerSchedules() {
        try {
            return appointmentService.getAllStoreManagerSchedules();
        } catch (Exception e) {
            log.error("获取所有店长排班时间表失败", e);
            return Result.error("获取所有店长排班时间表失败：" + e.getMessage());
        }
    }
    
    /**
     * 根据店长ID获取排班时间表
     */
    @GetMapping("/schedule/{storeManagerId}")
    @RequirePermission("user:schedule:view")
    public Result<StoreManagerScheduleVO> getStoreManagerSchedule(@PathVariable Long storeManagerId) {
        try {
            return appointmentService.getStoreManagerSchedule(storeManagerId);
        } catch (Exception e) {
            log.error("获取店长排班时间表失败", e);
            return Result.error("获取店长排班时间表失败：" + e.getMessage());
        }
    }
    
    /**
     * 确认预约
     */
    @PutMapping("/confirm/{id}")
    @RequirePermission("admin:appointment:confirm")
    public Result<Void> confirmAppointment(@PathVariable Long id) {
        try {
            return appointmentService.confirmAppointment(id);
        } catch (Exception e) {
            log.error("确认预约失败", e);
            return Result.error("确认预约失败：" + e.getMessage());
        }
    }
    
    /**
     * 完成预约
     */
    @PutMapping("/complete/{id}")
    @RequirePermission("store:appointment:complete")
    public Result<Void> completeAppointment(@PathVariable Long id) {
        try {
            return appointmentService.completeAppointment(id);
        } catch (Exception e) {
            log.error("完成预约失败", e);
            return Result.error("完成预约失败：" + e.getMessage());
        }
    }
    
    /**
     * 获取店长在特定日期的可用时间段
     */
    @GetMapping("/available-hours/{storeManagerId}/{appointmentDate}")
    @RequirePermission("user:appointment:view")
    public Result<List<Integer>> getStoreManagerAvailableHours(
            @PathVariable Long storeManagerId,
            @PathVariable @DateTimeFormat(pattern = "yyyy-MM-dd") LocalDate appointmentDate) {
        try {
            return appointmentService.getStoreManagerAvailableHours(storeManagerId, appointmentDate);
        } catch (Exception e) {
            log.error("获取店长可用时间段失败", e);
            return Result.error("获取店长可用时间段失败：" + e.getMessage());
        }
    }
    
    /**
     * 根据日期获取所有有排班的发型师
     */
    @GetMapping("/available-managers/{appointmentDate}")
    @RequirePermission("user:appointment:view")
    public Result<List<StoreManagerScheduleVO>> getAvailableStoreManagersByDate(
            @PathVariable @DateTimeFormat(pattern = "yyyy-MM-dd") LocalDate appointmentDate) {
        try {
            return appointmentService.getAvailableStoreManagersByDate(appointmentDate);
        } catch (Exception e) {
            log.error("根据日期获取可用发型师失败", e);
            return Result.error("根据日期获取可用发型师失败：" + e.getMessage());
        }
    }
    
    /**
     * 根据发型师ID获取其未来可用的日期排班
     */
    @GetMapping("/available-dates/{storeManagerId}")
    @RequirePermission("user:appointment:view")
    public Result<Map<String, List<Integer>>> getStoreManagerAvailableDates(
            @PathVariable Long storeManagerId,
            @RequestParam(defaultValue = "7") int days) {
        try {
            return appointmentService.getStoreManagerAvailableDates(storeManagerId, days);
        } catch (Exception e) {
            log.error("获取店长可用日期失败", e);
            return Result.error("获取店长可用日期失败：" + e.getMessage());
        }
    }
    
    /**
     * 获取店长在特定日期的时间段可用性信息（包含剩余名额）
     */
    @GetMapping("/time-slot-availability/{storeManagerId}/{appointmentDate}")
    @RequirePermission("user:appointment:view")
    public Result<List<TimeSlotAvailabilityVO>> getStoreManagerTimeSlotAvailability(
            @PathVariable Long storeManagerId,
            @PathVariable @DateTimeFormat(pattern = "yyyy-MM-dd") LocalDate appointmentDate) {
        try {
            return appointmentService.getStoreManagerTimeSlotAvailability(storeManagerId, appointmentDate);
        } catch (Exception e) {
            log.error("获取时间段可用性失败", e);
            return Result.error("获取时间段可用性失败：" + e.getMessage());
        }
    }
} 